home *** CD-ROM | disk | FTP | other *** search
/ Pascal Super Library / Pascal Super Library (CW International)(1997).bin / LIBRARY / SLTPU70C / SLTPU.DOC < prev    next >
Text File  |  1993-09-15  |  19KB  |  386 lines

  1.  
  2.                      Searchlight Programmer's Library
  3.                                Documentation
  4.                   (c) Copyright 1993 Searchlight Software
  5.  
  6. I. INTRODUCTION
  7.  
  8. Searchlight Programmer's Library is a series of Turbo Pascal unit (TPU) 
  9. files which can be linked into Turbo Pascal programs, providing a wide range 
  10. of functions for manipulating Searchlight data files. Included are 
  11. procedures to access, add and delete users, members, messages and files from 
  12. SLBBS data structures.  
  13.  
  14. Units in this library provide low and midlevel file i/o operations 
  15. exclusively. No user input/output oriented procedures are provided.  
  16.  
  17. It is not the intention of this documentation to describe the Searchlight 
  18. data structures at their lowest level. In particular, the details of binary 
  19. tree management, free record management, and subboard message indexing are 
  20. not covered. Instead, the library functions provided by the various TPU 
  21. files automatically implement these data structures and spare the 
  22. applications programmer from having to re-invent the low level code for 
  23. doing so. We do explain the workings of mid to high level data structures 
  24. necessary for writing complex programs that access the Searchlight database.  
  25.  
  26. This file provides general principles and recommendations for using the TPU 
  27. library for various types of applications. For more information, consult:
  28.  
  29. SLTPU.REF    - Complete reference to provided procedures and functions.
  30. FILEDEF.REF  - Record layouts provided by the FILEDEF.TPU unit.
  31. BLOCK.REF    - Record layouts provided in the BLOCK.TPU unit.
  32. STYLEDEF.REF - Record layouts for the STYLEDEF.TPU unit.
  33. SAMPLE?.PAS  - Example programs.
  34.  
  35.  
  36. II. UNIT INSTALLATION AND USEAGE
  37.  
  38. The TPU files contained in this development package are designed to work 
  39. with a particular version of Turbo Pascal. Before using these units you 
  40. must be sure that you have the correct version of the TPU files to match the 
  41. version of Turbo Pascal you will be using. Versions for the various 
  42. editions of Turbo Pascal are available on the Searchlight Support BBS (516-
  43. 689-2566).
  44.  
  45. The TPU files should be copied to your hard drive into either a working 
  46. directory where programs are to be developed, a directory containing other 
  47. TPU files or a separate directory. If the TPU files are not in the current 
  48. directory when you run Turbo Pascal, set Turbo's TPU path to point to the 
  49. directory where they are stored.
  50.  
  51. To use these units in your programs, simply declare the unit name in your 
  52. program's USES clause. See sample programs for examples.
  53.  
  54.  
  55. 2A. Existing Programs
  56.  
  57. Many of the TPU files in this library assume that you will be using the 
  58. global variables found in those units; for example, the POST unit works with 
  59. the global variable 'MainSub', which defines the current subboard.
  60.  
  61. Because of this situation, care should be taken when incorporating these 
  62. units into existing programs. In particular, existing low level code used 
  63. to manage data files should be discarded entirely in favor of direct calls 
  64. to the library procedures. Be aware of the global variables declared in 
  65. units such as FILEDEF, USERS and MEMBERS, and be sure that these do not 
  66. conflict with locally declared variables.
  67.  
  68. Wherever possible, we recommend building new applications from scratch 
  69. rather than converting existing programs.
  70.  
  71.  
  72. 2B. Other Languages
  73.  
  74. The TPU library is designed for use with Turbo Pascal. In order to get the 
  75. most out of these tools, we recommend you do all of your development with a 
  76. Turbo Pascal compiler. 
  77.  
  78. If you must do development in another environment, here are some 
  79. recommendations:
  80.  
  81. (1) The functions found in MODEM.PAS for accessing Searchlight's serial port 
  82. drivers are basically 8086 assembly language function calls. These are 
  83. readily translated into other languages. The source code should be self-
  84. explanatory.
  85.  
  86. (2) Searchlight's flat files, such as the CONFIG file, can be accessed from 
  87. any language simply by converting the Pascal record layout to the proper 
  88. structure, or by computing the byte offsets to the required variables. The 
  89. same technique will work for the in-memory variables used in MODEM.PAS.
  90.  
  91. It is NOT recommended that you attempt to write your own procedures for 
  92. accessing Searchlight's more complex data files, such as the user file or 
  93. message subboard files. These files use a complex system of indexes and 
  94. linked lists which the Pascal library code manages for you.
  95.  
  96. (3) If you wish to write your main application in another language but still 
  97. have access to the SLTPU functions, consider writing a separate program in 
  98. Turbo Pascal that can be accessed by your main program. For example, your 
  99. main program could call a separate EXE file written in Pascal when it needs 
  100. to perform a function such as saving a message. Or you could write a TSR 
  101. type of program that provides services via INT functions to your main 
  102. program.
  103.  
  104.  
  105.  
  106. III. READING MESSAGES
  107.  
  108. Each message in a Searchlight BBS subboard (which includes the Mail and 
  109. Bulletin subboards) consists of two basic elements: the message header, and 
  110. the message text. Headers are stored in the subboard's header (HDR) file, 
  111. and text in the message (MSG) file.
  112.  
  113. Message headers contain all of the information about a message other than 
  114. the text lines of the message itself. This includes such information as who 
  115. the message is from and who it's to; the date and time the message was 
  116. posted; and the message's subject. It also includes information about how 
  117. the message relates to other messages in the current subboard, ie. 
  118. information about the next and previous message (in both sequential and 
  119. threaded order), pointers to the message's replies and its parent, etc.
  120. There is 1 header record (type 'HeaderType' as defined in FILEDEF.PAS) per 
  121. message.
  122.  
  123. Each message contains a pointer to the message's text in the MSG file. Text 
  124. consists of one or more records, depending on the size of the message. The 
  125. packing and unpacking of these blocks is automatically handled by the 
  126. library procedures; programmers need only be familiar with the in-memory 
  127. representation as described in the accompanying reference manual.
  128.  
  129. There are 3 ways to locate a message's header file (and thus the message 
  130. itself) on disk: by record number, by message number, or by an internal 
  131. number called the UID or Universal ID value.
  132.  
  133. Record number refers to the physical location of the header record in the 
  134. header file. If the record number of a particular header is know, it can be 
  135. retrieved simply by reading the record from disk.
  136.  
  137. Message number refers to the sequential number assigned to each message in a 
  138. subboard; this is the number you usually see when reading the message in 
  139. Searchlight BBS (however note that certain commands, notably the MAIL 
  140. command, do not display the actual message numbers of messages but instead 
  141. display sequential numbers for convenience).
  142.  
  143. UID values are 32 bit numbers computed from the date and time a message is 
  144. posted plus a 7 bit random value. UID's are designed to provide a universal 
  145. way of identifying any message created on any subboard or even on any BBS, 
  146. and should stay with the message when it is imported and exported.  Since 
  147. the thread pointers in Searchlight are keyed to UID values rather than 
  148. message numbers, threading can be maintained even when messages are exported 
  149. to other subboards or other BBS systems.
  150.  
  151. It is very important to make the distinction between message numbers, UID 
  152. numbers and record numbers. A record number is simply a physical location, 
  153. which may bear no relationship to the message number, UID number, age of the 
  154. message, or anything else. Message and UID numbers are a logical values 
  155. stored within the header of the message itself. When you know the message 
  156. number or UID of a given message and wish to retrieve its header, you can do 
  157. so only by searching for the header. Fortunately, Searchlight subboards 
  158. implement an index which makes such searching for either value very fast.  
  159. In this library, you can search via the index simply by using the 
  160. 'FindHeader' command implemented in MESSAGE.TPU (see SLTPU.REF for more 
  161. information).
  162.  
  163.  
  164. 3A. Message Pointer Types
  165.  
  166. Message numbers, record numbers, and UID numbers are all stored as 32 bit 
  167. values in Searchlight (ie. LongInt values). To navagate a subboard 
  168. successfully, you need to know what kind of value each 32 bit pointer 
  169. represents.
  170.  
  171. Within the 'Headertype' variable, the pointers are:
  172.  
  173.        id: array[SEQ..UID]
  174.          of longint;         { sequential and universal ID numbers }
  175.  
  176. These are the Message Number and UID values of the message itself; Id[Seq] 
  177. is a message number, and Id[Uid] is a UID number.
  178.  
  179.        lastseq,
  180.        nextseq: longint;     { next/previous sequential message }
  181.  
  182. These values are message numbers. 'LastSeq' is the message number of the 
  183. previous message, and 'NextSeq' the number of the next message. If either 
  184. value is 0, it means that there is no last or next message. Notice that 
  185. since Searchlight does not renumber messages when a deletion occurs, the 
  186. next message number is not always equal to the current message number plus 
  187. 1, nor is the last message always the current message minus 1. Therefore, 
  188. use these pointers to traverse the message base as a linked list.
  189.  
  190.        lastthread,
  191.        nextthread: longint;  { next/previous threaded message }
  192.  
  193. All thread pointers are UID values: when you look up a message based on one 
  194. of these pointers, use the 'Uid' parameter to 'FindHeader'. The lastthread 
  195. and nextthread pointers form a linked list of messages in threaded order.  
  196. In order to follow a thread, simply follow this linked list instead of the 
  197. lastseq and nextseq pointers.
  198.  
  199.        topthread,            { first msg in this thread }
  200.        lastreply,            { last reply to this message }
  201.        replyto: longint;     { message to which this is a direct reply }
  202.  
  203. Again, these are UID values. 'Topthread' points to the first message in the 
  204. thread to which the current message belongs; 'Lastreply' points to the last 
  205. reply to the current message (0 if no replies) and 'Replyto' points to the 
  206. parent to this message (if the message is a reply).
  207.  
  208. All of the messages pointed to by these pointers will be part of the thread 
  209. formed by the 'lasttthread' and 'nextthread' pointers. You can use these 
  210. pointers primarily to define sub portions of a thread (such as the replies 
  211. to the current message) or to directly access special messages, such as the 
  212. message to which the current message replies. 
  213.  
  214.        lastmail,
  215.        nextmail: longint;    { next/previous personal mail message }
  216.  
  217. These are message numbers, and form a linked list pointing to all messages 
  218. in the current subboard which are addressed to the same user. In the MAIL 
  219. subboard, this linked list forms the user's mailbox and allows you to obtain 
  220. all the mail for a particular user without examining every message in the 
  221. subboard. The first mail message for a user (ie. the root of this list) is 
  222. stored in the user's Member record.
  223.  
  224. Notice that these pointers are active for all subboards, not just MAIL; they 
  225. can be used to obtain a list of messages addressed to a particular user on 
  226. any subboard.
  227.  
  228.        nextseqrec: longint;  { record # of next sequential msg }
  229.        nextmailrec: longint; { record # of next mail message }
  230.  
  231. These values are the only two record number values in the message header, 
  232. and point to the record number of the next sequential message and the next 
  233. mail message (ie. the actual record numbers of the messages pointed to by 
  234. 'Nextseq' and 'Nextmail').
  235.  
  236. The reason these two values are coded as record numbers is to allow speedy 
  237. processing of messages or MAIL in sequential order. When processing 
  238. headers, you can pass the value of 'NextSeqRec' or 'NextMailRec' as the last 
  239. parameter of FindHeader in order to speed up the search.
  240.  
  241.        (type Subtype)
  242.        firstmsg,
  243.        lastmsg: longint;       { first & last active msg by ID # }
  244.  
  245. These two message number values are stored in the header record of the 
  246. header file, and point to the first and last messages on the subboard.  
  247. These values are useful when you wish to begin processing an entire subboard 
  248. in forward or reverse order. Be sure to read the Subtype record from disk 
  249. right before using these values, as the values can change in multiuser 
  250. systems.
  251.  
  252.        (type MembType)
  253.        lastread: longint;     { highest message read }
  254.        firstmail,
  255.        lastmail: longint;     { first/last personal message this subboard }
  256.  
  257. The member record for a particular user in the current subboard contains 
  258. information about the user's highest message read, and pointers to the first 
  259. and last message to that user in the subboard (on the MAIL subboard, these 
  260. pointers define the user's mailbox). These values are message numbers.
  261.  
  262.  
  263. 3B. New Message Maintenance
  264.  
  265. The highest message read by a particular user on a particular subboard can 
  266. be obtained by retrieving the user's member record from the subboard member 
  267. file. The 'LastRead' field within the member record indicates the highest 
  268. message read.
  269.  
  270. To begin reading the next highest message, add 1 to this number and attempt 
  271. to read the message header from disk. For example, if the high message 
  272. number for a particular message is 100, attempt to read message 101. If no 
  273. message 101 exists (ie. if the FindHeader procedure returns a result of 0), 
  274. then try to read message 102, etc. until you either find the message, or 
  275. the number you are searching for is higher than the highest message on the 
  276. subboard (Mainsub.Subinfo.Lastmsg).
  277.  
  278. Don't forget to update the member's high message pointer when you are 
  279. finished, if that is required.
  280.  
  281.  
  282. 3C. Mailbox Access
  283.  
  284. To access a user's mail on the MAIL subboard, or all messages to that user 
  285. on any subboard, begin with the 'FirstMail' value in the member record for 
  286. that user. If no member record exists, or if the FirstMail value is zero, 
  287. then no mail or personal messages are available.
  288.  
  289. After reading the first mail message, the next can be obtained by following 
  290. the 'Nextmail' or 'Nextmailrec' pointer in the message's header file.
  291.  
  292. On the MAIL subboard, the 'LastRead' field in the member file is not used to 
  293. indicate where new mail messages begin. Instead, you should determine which 
  294. messages are new by the fact that the number of times read ('Rd') value in 
  295. the header is zero. If you wish to mark a new message as having been read, 
  296. increment this value and update the header on disk.
  297.  
  298.  
  299.  
  300. IV. IMPORTING AND EXPORTING
  301.  
  302. A major category of useful programs involves the importing of messages in 
  303. various external formats to Searchlight BBS message areas, and the export of 
  304. Searchlight messages to external files. Examples of such programs include 
  305. Searchlight's SLMAIL program, which provides echomail capability, and the 
  306. UTI drivers, which provide compatibility with PCRelay and Megamail offline 
  307. reader software.
  308.  
  309. The following discussion will be of use to anyone writing a program of this 
  310. type, including programs designed to allow Searchlight BBS systems to 
  311. communicate with network mail systems, offline reader software, or other 
  312. similar projects.
  313.  
  314.  
  315. 4A. Message Exporting
  316.  
  317. When exporting messages to an external file, try to preserve as much of the 
  318. header information as possible. Most formats include space for the message 
  319. 'To' and 'From' fields, as well as the subject.
  320.  
  321. If possible, try to preserve the outgoing message's UID number 
  322. (Header.Id[Uid]) and, if it is a reply, the UID number of the original 
  323. message (Header.ReplyTo). This will allow programs which import the message 
  324. into SLBBS systems to preserve the original threading associated with the 
  325. message.  
  326.  
  327. Many external message formats have a field for "Reference Number", which can 
  328. be used to contain the 'ReplyTo' link if the field is large enough to hold a 
  329. 4 byte integer value. In offline reader programs, you can store the message 
  330. number of the original message (as opposed to its UID value). This will 
  331. also allow threading to be maintained, but only if replies are imported into 
  332. the same subboard on the same BBS from which the original message was 
  333. exported. It is preferable to use UID numbers wherever possible, as these 
  334. will allow threading to be maintained even if messages are re-imported into 
  335. a different subboard.
  336.  
  337. When working with established data formats which do not provide an explicit 
  338. field for message UID number and reference (ReplyTo) number, try to encode 
  339. this information as part of the message text (for example, as a hidden line 
  340. if that is supported) or in an unused header field. Of course, you should 
  341. consult with the authors of the data format before using any fields which 
  342. might cause a problem for existing programs which process that format.
  343.  
  344. Most exportation programs will require a means to save the number of the 
  345. last message exported from a subboard, so that exportation of new messages 
  346. can begin at the next highest message. You can do this either externally in 
  347. your own file, or internally by creating a MEMBER record for your program in 
  348. the subboard's member file and updating the last read pointer there.
  349.  
  350.  
  351. 4B. Message Importing
  352.  
  353. When importing data from an external file format, try to determine whether 
  354. the message contains a Searchlight UID number and 'ReplyTo' UID value. If 
  355. these can be obtained from the external message, load the UID value into the 
  356. message header (Header.Id[Uid]) before saving the message and pass FALSE for 
  357. the 'SetUid' parameter of the 'MsgPost' function. Pass the ReplyTo value as 
  358. the 'Original' parameter to MsgPost.  
  359.  
  360. If you know the message number of the original message instead of the UID 
  361. value, you can pass this value times -1 to the MsgPost procedure. This will 
  362. work only if you are importing a reply to the same subboard in which the 
  363. original message was located (for example, in an offline reader system) and 
  364. no renumbering has occured. Do not attempt to use this method if you know 
  365. that messages may be imported into a different subboard (for example, in a 
  366. network mail situation).
  367.  
  368. If no message UID can be found in the external file, pass TRUE for 'SetUid'.  
  369. If no reference or replyto value can be found, you can either pass 0 for the 
  370. original message value, or, if it is customary for the system in which you 
  371. are working, try to determine the ID of the original message by comparing 
  372. the subject field of the message with other messages on the current 
  373. subboard.  
  374.  
  375. Searchlight expects messages to contain a maximum of 400 lines with a 
  376. maximum line length of 76 characters per line. If the incoming message 
  377. contains lines longer than 76 characters or if it is longer than 400 lines, 
  378. the message may need to be reformatted and/or truncated in order to fit 
  379. within Searchlight's boundaries. Message lines should not contain control 
  380. characters (ASCII values less than 32) but may contain extended IBM graphics 
  381. characters (ASCII values up to 255).
  382.  
  383.  
  384. (c) Copyright 1991-1993 Searchlight Software
  385.  
  386.